﻿using AdvVerifyModels.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace AdvVerifyModels.SubstrateTracking
{
    [JsonPolymorphic]
    [JsonDerivedType(typeof(FoupOpenEvent), typeDiscriminator: "FoupOpen")]
    [JsonDerivedType(typeof(FoupClosedEvent), typeDiscriminator: "FoupClosed")]
    [JsonDerivedType(typeof(FoupErrorEvent), typeDiscriminator: "FoupError")]
    [JsonDerivedType(typeof(FoupStateChangedEvent), typeDiscriminator: "FoupStateChanged")]
    [JsonDerivedType(typeof(WaferTransferStartEvent), typeDiscriminator: "WaferTransferStart")]
    [JsonDerivedType(typeof(WaferTransferEndEvent), typeDiscriminator: "WaferTransferEnd")]
    [JsonDerivedType(typeof(WaferStateChangedEvent), typeDiscriminator: "WaferStateChanged")]
    [JsonDerivedType(typeof(WaferTransferErrorEvent), typeDiscriminator: "WaferTransferError")]
    [JsonDerivedType(typeof(WaferTransferEvent), typeDiscriminator: "WaferTransfer")]
    [JsonDerivedType(typeof(WaferSwapEvent), typeDiscriminator: "WaferSwap")]
    [JsonDerivedType(typeof(ManuallySetLocationEvent), typeDiscriminator: "ManuallySetLocation")]
    [JsonDerivedType(typeof(ManuallyCreateWaferEvent), typeDiscriminator: "ManuallyCreateWafer")]
    [JsonDerivedType(typeof(ManuallyDeleteWaferEvent), typeDiscriminator: "ManuallyDeleteWafer")]
    [JsonDerivedType(typeof(ManuallyModifyWaferEvent), typeDiscriminator: "ManuallyModifyWafer")]

    public abstract class SubstrateTrackingEvent
    {
        // auto-generated
        public string Id { get; set; } = "";

        public required Guid TrackingId { get; set; }
    }

    public class FoupOpenEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public required WaferState[] Slots { get; set; }
    }

    public class FoupClosedEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }
    }

    public class FoupStateChangedEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public FoupState State { get; set; }
    }

    public class FoupErrorEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public string Message { get; set; } = "";
    }

    public class WaferTransferStartEvent : SubstrateTrackingEvent
    {
    }

    public class WaferTransferEndEvent : SubstrateTrackingEvent
    {
    }

    public class WaferStateChangedEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public int Slot { get; set; }

        public WaferState State { get; set; }
    }

    public class WaferTransferErrorEvent : SubstrateTrackingEvent
    {
        public string Message { get; set; } = "";
    }

    public class WaferTransferEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public int Slot { get; set; }

        public WaferLocation From { get; set; }

        public WaferLocation To { get; set; }
    }

    public class WaferSwapEvent : SubstrateTrackingEvent
    {
        public int FoupIn { get; set; }

        public int SlotIn { get; set; }

        public WaferLocation LocationOut { get; set; }

        public int FoupOut { get; set; }

        public int SlotOut { get; set; }

        public WaferLocation LocationIn { get; set; }
    }

    public class ManuallySetLocationEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public int Slot { get; set; }

        /// <summary>
        /// IsDelete为True时，代表被删除的片子的位置，IsDelete为false时，代表新片子的位置
        /// </summary>
        public WaferLocation Location { get; set; }

        public bool IsDelete { get; set; }
    }

    public class ManuallyCreateWaferEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public int Slot { get; set; }
    }

    public class ManuallyDeleteWaferEvent : SubstrateTrackingEvent
    {
        public int Foup { get; set; }

        public int Slot { get; set; }
    }


    public class ManuallyModifyWaferEvent : SubstrateTrackingEvent
    {
        public int OldFoup { get; set; }

        public int OldSlot { get; set; }

        public int NewFoup { get; set; }

        public int NewSlot { get; set; }

        public WaferLocation Location { get; set; }
    }
}
